<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>WebRTC Demo</title>
    <style>
        video { width: 45%; margin: 10px; }
        button { padding: 10px 20px; font-size: 16px; margin: 5px; }
        #openCameraButton:disabled { background-color: #cccccc; cursor: not-allowed; }
    </style>
</head>
<body>
<h1>WebRTC Demo</h1>
<video id="localVideo" autoplay playsinline></video>
<video id="remoteVideo" autoplay playsinline></video>
<button id="openCameraButton" disabled>打开摄像头</button>
<script>
    const localVideo = document.getElementById('localVideo');
    const remoteVideo = document.getElementById('remoteVideo');
    const openCameraButton = document.getElementById('openCameraButton');

    let localStream;
    let peerConnection;

    // 日志函数，添加时间戳
    function log(message) {
        console.log(`[${new Date().toISOString()}] ${message}`);
    }

    // 初始化WebSocket
    const ws = new WebSocket('ws://localhost:8888/ws');
    log('Initiating WebSocket connection');

    // WebSocket事件
    ws.onopen = () => {
        log('WebSocket connection established');
        openCameraButton.disabled = false;
    };

    ws.onmessage = async (event) => {
        log(`Received WebSocket message: ${event.data}`);
        try {
            const message = JSON.parse(event.data);
            if (message.type === 'answer') {
                log(`Processing answer SDP: ${JSON.stringify(message.sdp).slice(0, 100)}...`);
                await peerConnection.setRemoteDescription(new RTCSessionDescription(message));
                log('Set remote description successfully');
            } else if (message.type === 'ice') {
                log(`Processing ICE candidate: ${JSON.stringify(message.candidate).slice(0, 100)}...`);
                await peerConnection.addIceCandidate(new RTCIceCandidate(message));
                log('Added ICE candidate successfully');
            } else {
                log(`Unknown message type: ${message.type}`);
            }
        } catch (error) {
            log(`Error processing WebSocket message: ${error.message}`);
        }
    };

    ws.onerror = (error) => log(`WebSocket error: ${error}`);
    ws.onclose = () => {
        log('WebSocket connection closed');
        openCameraButton.disabled = true;
    };

    async function openCameraAndStartCall() {
        log('Open camera button clicked');
        try {
            // 获取本地音视频流
            log('Requesting media devices (video/audio)');
            localStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
            log('Media stream acquired successfully');
            localVideo.srcObject = localStream;

            // 创建WebRTC PeerConnection
            log('Creating RTCPeerConnection');
            peerConnection = new RTCPeerConnection({
                iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
            });

            // 添加本地流
            log('Adding local stream tracks to PeerConnection');
            localStream.getTracks().forEach(track => {
                peerConnection.addTrack(track, localStream);
                log(`Added track: ${track.kind}`);
            });

            // 处理ICE候选者
            peerConnection.onicecandidate = (event) => {
                if (event.candidate) {
                    log(`Sending ICE candidate: ${JSON.stringify(event.candidate).slice(0, 100)}...`);
                    ws.send(JSON.stringify({ type: 'ice', candidate: event.candidate }));
                }
            };

            // 显示远程视频流
            peerConnection.ontrack = (event) => {
                log('Received remote stream');
                remoteVideo.srcObject = event.streams[0];
            };

            // 创建并发送Offer
            log('Creating WebRTC offer');
            const offer = await peerConnection.createOffer();
            log(`Generated offer SDP: ${JSON.stringify(offer).slice(0, 100)}...`);
            await peerConnection.setLocalDescription(offer);
            log('Set local description successfully');
            ws.send(JSON.stringify({ type: 'offer', sdp: offer }));
            log('Sent offer to server');

            openCameraButton.disabled = true;
        } catch (error) {
            log(`Error in openCameraAndStartCall: ${error.message}`);
            alert('无法获取视频和音频，请检查设备权限');
        }
    }

    openCameraButton.onclick = openCameraAndStartCall;
</script>
</body>
</html>